package org.sunrise.game.common.network.client;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import lombok.Getter;
import org.sunrise.game.common.log.LogCore;
import org.sunrise.game.common.network.message.MessageType;
import org.sunrise.game.common.network.message.SocketMessage;
import org.sunrise.game.common.utils.Utils;

import java.nio.charset.StandardCharsets;

public class BaseClientHandler extends SimpleChannelInboundHandler<SocketMessage> {
    @Getter
    private final String nodeId;
    private boolean isAuthMessage = true;

    public BaseClientHandler(String nodeId) {
        this.nodeId = nodeId;
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) {
        String connectMessage = Utils.CLIENT_CONNECT + nodeId;
        ctx.writeAndFlush(new SocketMessage(MessageType.biz, connectMessage.getBytes(StandardCharsets.UTF_8)));
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, SocketMessage socketMessage) {
        byte[] data = socketMessage.getData();
        if (isAuthMessage) {
            String responseMessage = new String(data, StandardCharsets.UTF_8);
            if (responseMessage.startsWith(Utils.CLIENT_CONNECT_RESPONSE + Utils.SUCCESS)) {
                String serverNodeId = responseMessage.substring(Utils.CLIENT_CONNECT_RESPONSE.length() + Utils.SUCCESS.length());
                BaseClientManager.getBaseClient(nodeId).setServerNodeId(serverNodeId);
                LogCore.Client.info("connected to server success, cur NodeId = { {} }, serverNodeId = { {} } remoteAddress = { {} }", nodeId, serverNodeId, ctx.channel().remoteAddress());

            } else {
                LogCore.Client.error("connected to server failed, cur NodeId = { {} }", nodeId);
            }
            isAuthMessage = false;
        } else {
            BaseClientManager.recvFromServer(nodeId, data);
        }
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        super.channelInactive(ctx);
        BaseClientManager.getBaseClient(nodeId).setServerChannel(null);
        LogCore.Client.error("server disconnected, cur NodeId = { {} }, remoteAddress = {}", nodeId, ctx.channel().remoteAddress());
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        LogCore.Client.error("Exception caught: cur nodeId = { {} },  {}", nodeId, cause.getMessage());
    }
}